#ifndef SESSION_H
#define SESSION_H

#include <string>
#include <chrono>
#include <unordered_map>
#include <memory>

// 注意：
// Session用到SessionManager，SessionManager用到Session
// 1. Session.h包含SessionManager.h，SessionManager.h包含Session.h，有循环依赖
// 2. SessionManager.h包含Session.h
// Session.h前置声明让名字可见，指针引用放在.h
// Session.cpp包含Session.h让定义可见，使用manager_逻辑放在.cpp
class SessionManager;

// 在成员函数里shared_from_this()把自己（无法用this）作为shared_ptr<>传给外部使用
// 这里是给manager->storage更新
class Session : public std::enable_shared_from_this<Session>
{
public:
    Session(SessionManager *manager, const std::string &id, int expiryPeriod = 3600) // 默认1小时过期
        : manager_(manager), id_(id), expiryPeriod_(expiryPeriod)
    {
        this->refreshExpiryTime();
    }

    void setManager(SessionManager *manager)
    {
        this->manager_ = manager;
    }
    SessionManager *getManager() const
    {
        return this->manager_;
    }

    std::string getId() const
    {
        return this->id_;
    }

    void refreshExpiryTime() // 实际是刷新过期时间点
    {
        this->expiryTime_ = std::chrono::system_clock::now() + std::chrono::seconds(this->expiryPeriod_);
    }
    bool isExpired() const // 是否过期
    {
        return std::chrono::system_clock::now() > this->expiryTime_;
    }

    void setData(const std::string &key, const std::string &value);
    std::string getData(const std::string &key) const
    {
        auto it = this->data_.find(key);
        if (it == this->data_.end())
        {
            return "";
        }
        return it->second;
    }
    void deleteData(const std::string &key)
    {
        this->data_.erase(key);
    }
    void clearData()
    {
        this->data_.clear();
    }

private:
    SessionManager *manager_;

    std::string id_;
    int expiryPeriod_;                                 // 过期时间段（秒；创建后多久过期）
    std::chrono::system_clock::time_point expiryTime_; // 过期时间点（什么时候过期）
    std::unordered_map<std::string, std::string> data_;
};

#endif // SESSION_H